Descrição do Ator
Johnny Depp é um ator, músico, produtor de cinema e diretor americano muito conhecido por interpretar grandes personangens como o Capitão Jack Sparrow na franquia Piratas do Caribe, Edward Scissorhands do filme Edward mãos de tesoura, além de interpretar outros personagens famosos, como o bruxo das trevas Gellert Grindelwald em Animais Fantásticos e Onde Habitam, de 2016, e Animais Fantásticos: Os Crimes de Grindelwald de 2018, Willy Wonka em A Fantástica Fábrica de Chocolate e o Chapeleiro Maluco nos filmes Alice no País das Maravilhas e Alice através do Espelho.
Seus filmes de maior bilheteria foram a série Piratas do Caribe com um total de 4.524 bilhões de dólares, seguido pela franquia Animais Fantásticos e Onde Habitam com 1.457 bilhão, Alice no País das Maravilhas com 1.323 bilhão em receita global.Trata-se de um ator renomadisímo de Hollywood, com mais de 250 indicações a prêmios por seu trabalho, incluindo Oscars, Globo de Ouro e Screen Actors Guild.
Depp é um dos maiores e mais bem sucedidos atores de sua geração, juntamente com Brad Pitt, Will Smith, Robert Downey Jr., Tom Cruise e Leonardo DiCaprio. o artista conta com uma imensidão de filmes em seu currículo. Aqui neste post trabalhamos com uma amostra de 29 filmes coletados pelo Rotten Tomatoes.
Bilheteria por ano
Podemos perceber que a maioria dos filmes alcançaram uma bilheteria até 200 milhoes de dólares. Mas não foram poucos os filmes que despontaram em bilheteria, a frânquia de Piratas do caribe, rendeu uma boa grana ao Capitão Jack Sparrow.
p = filmes %>%
ggplot(aes(x = ano, y = bilheteria, label=filme)) +
geom_point(color = paleta[2], size = 4)
ggplotly(p)
O gráfico abaixo reforça a ideia de que a maioria dos filmes estrelados por Johnny Depp não obteve tanto sucesso quanto a frânquia de Piratas do caribe. O único filme que chegou próximo foi, Alice no país das maravilhas. Algo a ser considerado nesta base de dados é que o filme mais recente analisado é de 2017 e que de lá pra cá o Ator ja estrelou em outros grandes filmes que renderam bilheterias estrondosas, como por exemplo: ALICE ATRAVÉS DO ESPELHO e ANIMAIS FANTÁSTICOS E ONDE HABITAM.
filmes %>%
ggplot(aes(x = bilheteria)) +
geom_histogram(binwidth = 15, fill = paleta[4], color = "white")+
ylab("Quantidade")

E a avaliação geral dos filmes ???
Levando em consideração uma escala de 0-100, 18 dos 29 filmes citados em nossa base de dados tiveram uma avaliação positiva (considerando que positivo seria uma avaliação acima de 5). O filme com a melhor avaliação foi Deep Sea, seguido de GOnzo e Rango, que não foram filmes que renderam uma bilheteria muito alta, mas pra quem foi e assistiu, podemos ter certeza que não se arrependeram.
filmes %>%
ggplot(aes(x = reorder(filme,avaliacao), y=avaliacao, fill = paleta[4], color = "white")) +
geom_point(show.legend = FALSE)+
coord_flip()+
labs(x="Filme", y="Avaliação")

filmes %>%
ggplot(aes(x = avaliacao)) +
geom_histogram(binwidth = 10, boundary = 0, fill = paleta[4], color = "white") +
geom_rug(size = .5)+
ylab("Quantidade")

Nem sempre bilheteria é sinônimo de boas avaliações !!
Ao analisarmos o valor apróximado das bilheterias por ano, e compararmos com o valor aproximado das avaliações por ano, podemos perceber que nem sempre uma bilheteria muito alta significa dizer que o filme foi muito bom. Em 2010 a bilheteria dos filmes estrelados por Depp foram altíssimas, nesta época os filmes Alice no país das Maravilhas e O turista eram lançados. Entretanto as avaliaçoes medianas deles não refletiram na bilheteria que tiveram. Uma possível explicação para esta situação é que os fãs da literatura de Alice estavam bastante anciosos para terem a história recontada e atualizada nas telonas do cinema, a ponto de que qualquer deslize seria o suficiente para diminuir a nota de avaliação. Outra pssível justificativa é que talvez o filme tenha sido ruim mesmo. Cabe ao cinelunático julgar.
bilheteria_ano = filmes %>%
group_by(ano) %>%
summarise(bilheteria_mediana=median(bilheteria))
avaliacao_ano = filmes %>%
group_by(ano) %>%
summarise(avaliacao_mediana=median(avaliacao))
p = bilheteria_ano %>%
ggplot(aes(x=ano, y=bilheteria_mediana))+
geom_line(color=paleta[2])+
geom_point(color="red")
p2 = avaliacao_ano %>%
ggplot(aes(x=ano, y=avaliacao_mediana))+
geom_line(color=paleta[2])+
geom_point(color="red")
filmes %>%
filter(ano == 2010) %>%
select(filme) %>%
glimpse()
Observations: 2
Variables: 1
$ filme <chr> "The Tourist", "Alice in Wonderland"
ggplotly(p)
ggplotly(p2)
Como posso agrupar os filmes do Depp em categorias?
Normalização das variáveis
Para tentar agrupar os filmes em grupos, é importante perceber que as escalas de bilheteria e avaliação são bem diferentes. O espectro de bilheteria é bem maior que o espectro de avaliação. Isso pode gerar um agrupamento errado ou confuso. Logo o primeiro passo a ser feito é a normalização dos dados.
m_transformado = filmes %>%
mutate(bilheteria_log = as.vector(scale(log10(bilheteria))),
avaliacao_scaled = as.vector(scale(avaliacao)))
summary(m_transformado %>% select(bilheteria_log, avaliacao_scaled))
bilheteria_log avaliacao_scaled
Min. :-2.5870 Min. :-1.85100
1st Qu.:-0.3505 1st Qu.:-0.96059
Median : 0.1808 Median : 0.05702
Mean : 0.0000 Mean : 0.00000
3rd Qu.: 0.5830 3rd Qu.: 0.73543
Max. : 1.4119 Max. : 1.49864
Em quantos grupos eu posso dividir minha base de dados ?
Após os dados normalizados, podemos perceber que as escalas ficaram ao menos perto uma da outra, diferente de momentos anteriores. O próximo passo é decidir em quantos grupos executar o algoritimo de K-means, dependendo da escolha, os grupos podem não ser favorecidos. Para certificar de que se fez a melhor escolha de K, utilizou-se a função de “Gap Static Calculation”, que basicamente retorna pra nós os desempenhos simulados de alguns Ks, e partir de então se torna decisão do usuário.
plot_clusgap = function(clusgap, title = "Gap Statistic calculation results") {
require("ggplot2")
gstab = data.frame(clusgap$Tab, k = 1:nrow(clusgap$Tab))
p = ggplot(gstab, aes(k, gap)) + geom_line() + geom_point(size = 5)
p = p + geom_errorbar(aes(ymax = gap + SE.sim, ymin = gap - SE.sim), width = .2)
p = p + ggtitle(title)
return(p)
}
gaps <- m_transformado %>%
select(bilheteria_log, avaliacao) %>%
clusGap(FUN = kmeans, nstart = 20, K.max = 8, B = 200)
Clustering k = 1,2,..., K.max (= 8): .. done
Bootstrapping, b = 1,2,..., B (= 200) [one "." per sample]:
.................................................. 50
.................................................. 100
.................................................. 150
.................................................. 200
plot_clusgap(gaps)

Com a execução do Gap Statics é possível perceber que em 5 grupos temos um valor bastante interessante
set.seed(12345)
n_clusters = 5
# O agrupamento de fato:
cluster = m_transformado %>%
select(bilheteria_log, avaliacao_scaled) %>%
kmeans(centers = n_clusters, nstart = 20)
agrupado = cluster %>%
augment(m_transformado)
#p = agrupado %>%
# ggplot(aes(x = avaliacao_scaled, y = bilheteria_log, color = .cluster)) +
# geom_point(size = 3)
p1 = agrupado %>%
ggplot(aes(x = avaliacao, y = bilheteria, color = .cluster, label=filme)) +
geom_point(size = 3)+
scale_y_log10()
ggscatter(agrupado, x="avaliacao", y="bilheteria", color=".cluster")+
stat_chull(aes(fill = .cluster), alpha=0.3, geom="polygon")+
xlab("Avaliação")+
ylab("Bilheteria")

ggplotly(p1)
LS0tCnRpdGxlOiAiVGlwb3MgZGUgZmlsbWUgZGUgSm9obm55IERlcHAiCmF1dGhvcjogIklnb3IgTWF0aGV1cyBDYXN0b3IgRGluaXogUGluaGVpcm8iCm91dHB1dDoKICAgIGh0bWxfZG9jdW1lbnQ6CiAgICAgICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICAgICAgdG9jOiB5ZXMKICAgICAgICB0b2NfZmxvYXQ6IHllcwogICAgaHRtbF9ub3RlYm9vazoKICAgICAgICB0b2M6IHllcwogICAgICAgIHRvY19mbG9hdDogeWVzCnRoZW1lOiBzYW5kc3RvbmUKLS0tCgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShoZXJlKQpsaWJyYXJ5KGNsdXN0ZXIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdnZGVuZHJvKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KGdncHVicikKCnNvdXJjZShoZXJlOjpoZXJlKCJjb2RlL2xpYi5SIikpCnRoZW1lX3NldCh0aGVtZV9yZXBvcnQoKSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldCh0aWR5ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA2LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDUsCiAgICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSkKCnBhbGV0YSA9IGMoIiM0MDRFNEQiLAogICAgICAgICAgICIjOTJEQ0U1IiwKICAgICAgICAgICAiIzkzOEJBMSIsCiAgICAgICAgICAgIiMyRDMxNDIiLAogICAgICAgICAgICIjRjQ3NDNCIikKYGBgCgpgYGB7cn0KaW1wb3J0X2RhdGEoImpvaG5ueV9kZXBwIikKYGBgCgoKYGBge3IgcmVhZH0KZmlsbWVzID0gcmVhZF9pbXBvcnRlZF9kYXRhKCkKYGBgCgojIERlc2NyacOnw6NvIGRvIEF0b3IKCkpvaG5ueSBEZXBwIMOpIHVtIGF0b3IsIG3DunNpY28sIHByb2R1dG9yIGRlIGNpbmVtYSBlIGRpcmV0b3IgYW1lcmljYW5vIG11aXRvIGNvbmhlY2lkbyBwb3IgaW50ZXJwcmV0YXIgZ3JhbmRlcyBwZXJzb25hbmdlbnMgY29tbyBvIENhcGl0w6NvIEphY2sgU3BhcnJvdyBuYSBmcmFucXVpYSBQaXJhdGFzIGRvIENhcmliZSwgRWR3YXJkIFNjaXNzb3JoYW5kcyBkbyBmaWxtZSBFZHdhcmQgbcOjb3MgZGUgdGVzb3VyYSwgYWzDqW0gZGUgaW50ZXJwcmV0YXIgb3V0cm9zIHBlcnNvbmFnZW5zIGZhbW9zb3MsIGNvbW8gbyBicnV4byBkYXMgdHJldmFzIEdlbGxlcnQgR3JpbmRlbHdhbGQgZW0gQW5pbWFpcyBGYW50w6FzdGljb3MgZSBPbmRlIEhhYml0YW0sIGRlIDIwMTYsIGUgQW5pbWFpcyBGYW50w6FzdGljb3M6IE9zIENyaW1lcyBkZSBHcmluZGVsd2FsZCBkZSAyMDE4LCBXaWxseSBXb25rYSBlbSBBIEZhbnTDoXN0aWNhIEbDoWJyaWNhIGRlIENob2NvbGF0ZSBlIG8gQ2hhcGVsZWlybyBNYWx1Y28gbm9zIGZpbG1lcyBBbGljZSBubyBQYcOtcyBkYXMgTWFyYXZpbGhhcyBlIEFsaWNlIGF0cmF2w6lzIGRvIEVzcGVsaG8uCgpTZXVzIGZpbG1lcyBkZSBtYWlvciBiaWxoZXRlcmlhIGZvcmFtIGEgc8OpcmllIFBpcmF0YXMgZG8gQ2FyaWJlIGNvbSB1bSB0b3RhbCBkZSA0LjUyNCBiaWxow7VlcyBkZSBkw7NsYXJlcywgc2VndWlkbyBwZWxhIGZyYW5xdWlhIEFuaW1haXMgRmFudMOhc3RpY29zIGUgT25kZSBIYWJpdGFtIGNvbSAxLjQ1NyBiaWxow6NvLCBBbGljZSBubyBQYcOtcyBkYXMgTWFyYXZpbGhhcyBjb20gMS4zMjMgYmlsaMOjbyBlbSByZWNlaXRhIGdsb2JhbC5UcmF0YS1zZSBkZSB1bSBhdG9yIHJlbm9tYWRpc8OtbW8gZGUgSG9sbHl3b29kLCBjb20gbWFpcyBkZSAyNTAgaW5kaWNhw6fDtWVzIGEgcHLDqm1pb3MgcG9yIHNldSB0cmFiYWxobywgaW5jbHVpbmRvIE9zY2FycywgR2xvYm8gZGUgT3VybyBlIFNjcmVlbiBBY3RvcnMgR3VpbGQuIAoKRGVwcCDDqSB1bSBkb3MgbWFpb3JlcyBlIG1haXMgYmVtIHN1Y2VkaWRvcyBhdG9yZXMgZGUgc3VhIGdlcmHDp8OjbywganVudGFtZW50ZSBjb20gQnJhZCBQaXR0LCBXaWxsIFNtaXRoLCBSb2JlcnQgRG93bmV5IEpyLiwgVG9tIENydWlzZSBlIExlb25hcmRvIERpQ2FwcmlvLiBvIGFydGlzdGEgY29udGEgY29tIHVtYSBpbWVuc2lkw6NvIGRlIGZpbG1lcyBlbSBzZXUgY3VycsOtY3Vsby4gQXF1aSBuZXN0ZSBwb3N0IHRyYWJhbGhhbW9zIGNvbSB1bWEgYW1vc3RyYSBkZSAyOSBmaWxtZXMgY29sZXRhZG9zIHBlbG8gUm90dGVuIFRvbWF0b2VzLiAKCiMjIEJpbGhldGVyaWEgcG9yIGFubwoKUG9kZW1vcyBwZXJjZWJlciBxdWUgYSBtYWlvcmlhIGRvcyBmaWxtZXMgYWxjYW7Dp2FyYW0gdW1hIGJpbGhldGVyaWEgYXTDqSAyMDAgbWlsaG9lcyBkZSBkw7NsYXJlcy4gTWFzIG7Do28gZm9yYW0gcG91Y29zIG9zIGZpbG1lcyBxdWUgZGVzcG9udGFyYW0gZW0gYmlsaGV0ZXJpYSwgYSBmcsOibnF1aWEgZGUgUGlyYXRhcyBkbyBjYXJpYmUsIHJlbmRldSB1bWEgYm9hIGdyYW5hIGFvIENhcGl0w6NvIEphY2sgU3BhcnJvdy4gCgpgYGB7cn0KCnAgPSBmaWxtZXMgJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gYW5vLCB5ID0gYmlsaGV0ZXJpYSwgbGFiZWw9ZmlsbWUpKSArIAogICAgZ2VvbV9wb2ludChjb2xvciA9IHBhbGV0YVsyXSwgc2l6ZSA9IDQpCgpnZ3Bsb3RseShwKQoKYGBgCgpPIGdyw6FmaWNvIGFiYWl4byByZWZvcsOnYSBhIGlkZWlhIGRlIHF1ZSBhIG1haW9yaWEgZG9zIGZpbG1lcyBlc3RyZWxhZG9zIHBvciBKb2hubnkgRGVwcCBuw6NvIG9idGV2ZSB0YW50byBzdWNlc3NvIHF1YW50byBhIGZyw6JucXVpYSBkZSBQaXJhdGFzIGRvIGNhcmliZS4gTyDDum5pY28gZmlsbWUgcXVlIGNoZWdvdSBwcsOzeGltbyBmb2ksIEFsaWNlIG5vIHBhw61zIGRhcyBtYXJhdmlsaGFzLiBBbGdvIGEgc2VyIGNvbnNpZGVyYWRvIG5lc3RhIGJhc2UgZGUgZGFkb3Mgw6kgcXVlIG8gZmlsbWUgbWFpcyByZWNlbnRlIGFuYWxpc2FkbyDDqSBkZSAyMDE3IGUgcXVlIGRlIGzDoSBwcmEgY8OhIG8gQXRvciBqYSBlc3RyZWxvdSBlbSBvdXRyb3MgZ3JhbmRlcyBmaWxtZXMgcXVlIHJlbmRlcmFtIGJpbGhldGVyaWFzIGVzdHJvbmRvc2FzLCBjb21vIHBvciBleGVtcGxvOiBBTElDRSBBVFJBVsOJUyBETyBFU1BFTEhPIGUgQU5JTUFJUyBGQU5Uw4FTVElDT1MgRSBPTkRFIEhBQklUQU0uCgpgYGB7cn0KZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IGJpbGhldGVyaWEpKSArIAogICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxNSwgZmlsbCA9IHBhbGV0YVs0XSwgY29sb3IgPSAid2hpdGUiKSsKICAgIHlsYWIoIlF1YW50aWRhZGUiKQpgYGAKCiMjIEUgYSBhdmFsaWHDp8OjbyBnZXJhbCBkb3MgZmlsbWVzID8/PwoKTGV2YW5kbyBlbSBjb25zaWRlcmHDp8OjbyB1bWEgZXNjYWxhIGRlIDAtMTAwLCAxOCBkb3MgMjkgZmlsbWVzIGNpdGFkb3MgZW0gbm9zc2EgYmFzZSBkZSBkYWRvcyB0aXZlcmFtIHVtYSBhdmFsaWHDp8OjbyBwb3NpdGl2YSAoY29uc2lkZXJhbmRvIHF1ZSBwb3NpdGl2byBzZXJpYSB1bWEgYXZhbGlhw6fDo28gYWNpbWEgZGUgNSkuIE8gZmlsbWUgY29tIGEgbWVsaG9yIGF2YWxpYcOnw6NvIGZvaSBEZWVwIFNlYSwgc2VndWlkbyBkZSBHT256byBlIFJhbmdvLCBxdWUgbsOjbyBmb3JhbSBmaWxtZXMgcXVlIHJlbmRlcmFtIHVtYSBiaWxoZXRlcmlhIG11aXRvIGFsdGEsIG1hcyBwcmEgcXVlbSBmb2kgZSBhc3Npc3RpdSwgcG9kZW1vcyB0ZXIgY2VydGV6YSBxdWUgbsOjbyBzZSBhcnJlcGVuZGVyYW0uCgpgYGB7cn0KZmlsbWVzICU+JSAKICAgIGdncGxvdChhZXMoeCA9IHJlb3JkZXIoZmlsbWUsYXZhbGlhY2FvKSwgeT1hdmFsaWFjYW8sIGZpbGwgPSBwYWxldGFbNF0sIGNvbG9yID0gIndoaXRlIikpICsgCiAgICBnZW9tX3BvaW50KHNob3cubGVnZW5kID0gRkFMU0UpKwogICAgY29vcmRfZmxpcCgpKwogICAgbGFicyh4PSJGaWxtZSIsIHk9IkF2YWxpYcOnw6NvIikKCmZpbG1lcyAlPiUgCiAgICBnZ3Bsb3QoYWVzKHggPSBhdmFsaWFjYW8pKSArIAogICAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxMCwgYm91bmRhcnkgPSAwLCBmaWxsID0gcGFsZXRhWzRdLCBjb2xvciA9ICJ3aGl0ZSIpICsgCiAgICBnZW9tX3J1ZyhzaXplID0gLjUpKwogICAgeWxhYigiUXVhbnRpZGFkZSIpCmBgYAoKIyMgTmVtIHNlbXByZSBiaWxoZXRlcmlhIMOpIHNpbsO0bmltbyBkZSBib2FzIGF2YWxpYcOnw7VlcyAhIQoKQW8gYW5hbGlzYXJtb3MgbyB2YWxvciBhcHLDs3hpbWFkbyBkYXMgYmlsaGV0ZXJpYXMgcG9yIGFubywgZSBjb21wYXJhcm1vcyBjb20gbyB2YWxvciBhcHJveGltYWRvIGRhcyBhdmFsaWHDp8O1ZXMgcG9yIGFubywgcG9kZW1vcyBwZXJjZWJlciBxdWUgbmVtIHNlbXByZSB1bWEgYmlsaGV0ZXJpYSBtdWl0byBhbHRhIHNpZ25pZmljYSBkaXplciBxdWUgbyBmaWxtZSBmb2kgbXVpdG8gYm9tLiBFbSAyMDEwIGEgYmlsaGV0ZXJpYSBkb3MgZmlsbWVzIGVzdHJlbGFkb3MgcG9yIERlcHAgZm9yYW0gYWx0w61zc2ltYXMsIG5lc3RhIMOpcG9jYSBvcyBmaWxtZXMgQWxpY2Ugbm8gcGHDrXMgZGFzIE1hcmF2aWxoYXMgZSBPIHR1cmlzdGEgZXJhbSBsYW7Dp2Fkb3MuIEVudHJldGFudG8gYXMgYXZhbGlhw6dvZXMgbWVkaWFuYXMgZGVsZXMgbsOjbyByZWZsZXRpcmFtIG5hIGJpbGhldGVyaWEgcXVlIHRpdmVyYW0uIFVtYSBwb3Nzw612ZWwgZXhwbGljYcOnw6NvIHBhcmEgZXN0YSBzaXR1YcOnw6NvIMOpIHF1ZSBvcyBmw6NzIGRhIGxpdGVyYXR1cmEgZGUgQWxpY2UgZXN0YXZhbSBiYXN0YW50ZSBhbmNpb3NvcyBwYXJhIHRlcmVtIGEgaGlzdMOzcmlhIHJlY29udGFkYSBlIGF0dWFsaXphZGEgbmFzIHRlbG9uYXMgZG8gY2luZW1hLCBhIHBvbnRvIGRlIHF1ZSBxdWFscXVlciBkZXNsaXplIHNlcmlhIG8gc3VmaWNpZW50ZSBwYXJhIGRpbWludWlyIGEgbm90YSBkZSBhdmFsaWHDp8Ojby4gT3V0cmEgcHNzw612ZWwganVzdGlmaWNhdGl2YSDDqSBxdWUgdGFsdmV6IG8gZmlsbWUgdGVuaGEgc2lkbyBydWltIG1lc21vLiBDYWJlIGFvIGNpbmVsdW7DoXRpY28ganVsZ2FyLgoKYGBge3J9CmJpbGhldGVyaWFfYW5vID0gZmlsbWVzICU+JSAKICAgIGdyb3VwX2J5KGFubykgJT4lIAogICAgc3VtbWFyaXNlKGJpbGhldGVyaWFfbWVkaWFuYT1tZWRpYW4oYmlsaGV0ZXJpYSkpCgphdmFsaWFjYW9fYW5vID0gZmlsbWVzICU+JSAKICAgIGdyb3VwX2J5KGFubykgJT4lIAogICAgc3VtbWFyaXNlKGF2YWxpYWNhb19tZWRpYW5hPW1lZGlhbihhdmFsaWFjYW8pKQoKcCA9IGJpbGhldGVyaWFfYW5vICU+JSAKICAgIGdncGxvdChhZXMoeD1hbm8sIHk9YmlsaGV0ZXJpYV9tZWRpYW5hKSkrCiAgICBnZW9tX2xpbmUoY29sb3I9cGFsZXRhWzJdKSsKICAgIGdlb21fcG9pbnQoY29sb3I9InJlZCIpCgpwMiA9IGF2YWxpYWNhb19hbm8gJT4lIAogICAgZ2dwbG90KGFlcyh4PWFubywgeT1hdmFsaWFjYW9fbWVkaWFuYSkpKwogICAgZ2VvbV9saW5lKGNvbG9yPXBhbGV0YVsyXSkrCiAgICBnZW9tX3BvaW50KGNvbG9yPSJyZWQiKQoKZmlsbWVzICU+JSAKICAgIGZpbHRlcihhbm8gPT0gMjAxMCkgJT4lCiAgICBzZWxlY3QoZmlsbWUpICU+JSAKICAgIGdsaW1wc2UoKQoKZ2dwbG90bHkocCkKZ2dwbG90bHkocDIpCgpgYGAKCgojIENvbW8gcG9zc28gYWdydXBhciBvcyBmaWxtZXMgZG8gRGVwcCBlbSBjYXRlZ29yaWFzPwoKIyMgTm9ybWFsaXphw6fDo28gZGFzIHZhcmnDoXZlaXMKClBhcmEgdGVudGFyIGFncnVwYXIgb3MgZmlsbWVzIGVtIGdydXBvcywgw6kgaW1wb3J0YW50ZSBwZXJjZWJlciBxdWUgYXMgZXNjYWxhcyBkZSBiaWxoZXRlcmlhIGUgYXZhbGlhw6fDo28gc8OjbyBiZW0gZGlmZXJlbnRlcy4gTyBlc3BlY3RybyBkZSBiaWxoZXRlcmlhIMOpIGJlbSBtYWlvciBxdWUgbyBlc3BlY3RybyBkZSBhdmFsaWHDp8Ojby4gSXNzbyBwb2RlIGdlcmFyIHVtIGFncnVwYW1lbnRvIGVycmFkbyBvdSBjb25mdXNvLiBMb2dvIG8gcHJpbWVpcm8gcGFzc28gYSBzZXIgZmVpdG8gw6kgYSBub3JtYWxpemHDp8OjbyBkb3MgZGFkb3MuIAoKYGBge3J9Cm1fdHJhbnNmb3JtYWRvID0gZmlsbWVzICU+JSAKICAgIG11dGF0ZShiaWxoZXRlcmlhX2xvZyA9IGFzLnZlY3RvcihzY2FsZShsb2cxMChiaWxoZXRlcmlhKSkpLCAKICAgICAgICAgICBhdmFsaWFjYW9fc2NhbGVkID0gYXMudmVjdG9yKHNjYWxlKGF2YWxpYWNhbykpKQoKc3VtbWFyeShtX3RyYW5zZm9ybWFkbyAlPiUgc2VsZWN0KGJpbGhldGVyaWFfbG9nLCBhdmFsaWFjYW9fc2NhbGVkKSkKYGBgCgojIyBFbSBxdWFudG9zIGdydXBvcyBldSBwb3NzbyBkaXZpZGlyIG1pbmhhIGJhc2UgZGUgZGFkb3MgPwoKQXDDs3Mgb3MgZGFkb3Mgbm9ybWFsaXphZG9zLCBwb2RlbW9zIHBlcmNlYmVyIHF1ZSBhcyBlc2NhbGFzIGZpY2FyYW0gYW8gbWVub3MgcGVydG8gdW1hIGRhIG91dHJhLCBkaWZlcmVudGUgZGUgbW9tZW50b3MgYW50ZXJpb3Jlcy4gTyBwcsOzeGltbyBwYXNzbyDDqSBkZWNpZGlyIGVtIHF1YW50b3MgZ3J1cG9zIGV4ZWN1dGFyIG8gYWxnb3JpdGltbyBkZSBLLW1lYW5zLCBkZXBlbmRlbmRvIGRhIGVzY29saGEsIG9zIGdydXBvcyBwb2RlbSBuw6NvIHNlciBmYXZvcmVjaWRvcy4gUGFyYSBjZXJ0aWZpY2FyIGRlIHF1ZSBzZSBmZXogYSBtZWxob3IgZXNjb2xoYSBkZSBLLCB1dGlsaXpvdS1zZSBhIGZ1bsOnw6NvIGRlICJHYXAgU3RhdGljIENhbGN1bGF0aW9uIiwgcXVlIGJhc2ljYW1lbnRlIHJldG9ybmEgcHJhIG7Ds3Mgb3MgZGVzZW1wZW5ob3Mgc2ltdWxhZG9zIGRlIGFsZ3VucyBLcywgZSBwYXJ0aXIgZGUgZW50w6NvIHNlIHRvcm5hIGRlY2lzw6NvIGRvIHVzdcOhcmlvLgoKYGBge3J9CnBsb3RfY2x1c2dhcCA9IGZ1bmN0aW9uKGNsdXNnYXAsIHRpdGxlID0gIkdhcCBTdGF0aXN0aWMgY2FsY3VsYXRpb24gcmVzdWx0cyIpIHsKICAgIHJlcXVpcmUoImdncGxvdDIiKQogICAgZ3N0YWIgPSBkYXRhLmZyYW1lKGNsdXNnYXAkVGFiLCBrID0gMTpucm93KGNsdXNnYXAkVGFiKSkKICAgIHAgPSBnZ3Bsb3QoZ3N0YWIsIGFlcyhrLCBnYXApKSArIGdlb21fbGluZSgpICsgZ2VvbV9wb2ludChzaXplID0gNSkKICAgIHAgPSBwICsgZ2VvbV9lcnJvcmJhcihhZXMoeW1heCA9IGdhcCArIFNFLnNpbSwgeW1pbiA9IGdhcCAtIFNFLnNpbSksIHdpZHRoID0gLjIpCiAgICBwID0gcCArIGdndGl0bGUodGl0bGUpCiAgICByZXR1cm4ocCkKfQoKYGBgCgpgYGB7cn0KZ2FwcyA8LSBtX3RyYW5zZm9ybWFkbyAlPiUgCiAgICBzZWxlY3QoYmlsaGV0ZXJpYV9sb2csIGF2YWxpYWNhbykgJT4lIAogICAgY2x1c0dhcChGVU4gPSBrbWVhbnMsIG5zdGFydCA9IDIwLCBLLm1heCA9IDgsIEIgPSAyMDApCgpwbG90X2NsdXNnYXAoZ2FwcykKYGBgCgpDb20gYSBleGVjdcOnw6NvIGRvIEdhcCBTdGF0aWNzIMOpIHBvc3PDrXZlbCBwZXJjZWJlciBxdWUgZW0gNSBncnVwb3MgdGVtb3MgdW0gdmFsb3IgYmFzdGFudGUgaW50ZXJlc3NhbnRlCgpgYGB7cn0Kc2V0LnNlZWQoMTIzNDUpCm5fY2x1c3RlcnMgPSA1CgojIE8gYWdydXBhbWVudG8gZGUgZmF0bzoKY2x1c3RlciA9IG1fdHJhbnNmb3JtYWRvICU+JSAKICAgIHNlbGVjdChiaWxoZXRlcmlhX2xvZywgYXZhbGlhY2FvX3NjYWxlZCkgJT4lIAogICAga21lYW5zKGNlbnRlcnMgPSBuX2NsdXN0ZXJzLCBuc3RhcnQgPSAyMCkKCmFncnVwYWRvID0gY2x1c3RlciAlPiUgCiAgICBhdWdtZW50KG1fdHJhbnNmb3JtYWRvKQoKI3AgPSBhZ3J1cGFkbyAlPiUgCiMgICAgZ2dwbG90KGFlcyh4ID0gYXZhbGlhY2FvX3NjYWxlZCwgeSA9IGJpbGhldGVyaWFfbG9nLCBjb2xvciA9IC5jbHVzdGVyKSkgICsgCiMgICAgZ2VvbV9wb2ludChzaXplID0gMykKCnAxID0gYWdydXBhZG8gJT4lIAogICAgZ2dwbG90KGFlcyh4ID0gYXZhbGlhY2FvLCB5ID0gYmlsaGV0ZXJpYSwgY29sb3IgPSAuY2x1c3RlciwgbGFiZWw9ZmlsbWUpKSAgKyAKICAgIGdlb21fcG9pbnQoc2l6ZSA9IDMpKwogICAgc2NhbGVfeV9sb2cxMCgpCgpnZ3NjYXR0ZXIoYWdydXBhZG8sIHg9ImF2YWxpYWNhbyIsIHk9ImJpbGhldGVyaWEiLCBjb2xvcj0iLmNsdXN0ZXIiKSsKICAgIHN0YXRfY2h1bGwoYWVzKGZpbGwgPSAuY2x1c3RlciksIGFscGhhPTAuMywgZ2VvbT0icG9seWdvbiIpKwogICAgeGxhYigiQXZhbGlhw6fDo28iKSsKICAgIHlsYWIoIkJpbGhldGVyaWEiKQoKZ2dwbG90bHkocDEpCgoKYGBgCgoKCgoK